package com.shockweb.register;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.shockweb.bridge.HostInfo;
import com.shockweb.bridge.ServerInfo;
import com.shockweb.client.ClientException;
import com.shockweb.client.impl.RegisterClient;
import com.shockweb.common.log.LogManager;
import com.shockweb.register.config.RegisterConfig;
import com.shockweb.register.data.ServiceRoot;

/**
 * 注册服务器同步数据的服务
 * 
 * @author 彭明华
 * 2018年1月3日 创建
 */
public class SyncThread implements Runnable{

	
	/**
	 * 当前同步服务实例
	 */
	private static SyncThread instance = null;
	
	/**
	 * 启动的同步线程
	 */
	private Thread thread = null;

	
	/**
	 * 获取当前实例
	 * @return
	 */
	public static SyncThread getInstance(){
		return instance;
	}
	
	
	/**
	 * 待同步的服务信息
	 */
	List<ServerInfo> clusterServerInfos = new ArrayList<ServerInfo>();
	
	/**
	 * 增加需要同步的信息
	 * @param infos
	 */
	public void addClusterServerInfo(ServerInfo info){
		synchronized(clusterServerInfos){
			this.clusterServerInfos.add(info);
		}
	}
	
	/**
	 * 待同步的服务器信息
	 */
	List<HostInfo> hostInfos = new ArrayList<HostInfo>();
	
	/**
	 * 添加待同步的服务器信息
	 * @param info
	 */
	public void addClusterHost(HostInfo info) {
		synchronized(hostInfos){
			this.hostInfos.add(info);
		}
	}
	
	/**
	 * 注册服务器的配置
	 */
	private RegisterConfig config = null;
	
	
	/**
	 * 保存需要同步的服务
	 */
	private Map<String,RegisterClient> servers = new HashMap<String,RegisterClient>();
	
	/**
	 * 启动服务
	 * @param servers
	 */
	public synchronized static void start(RegisterConfig config){
		if(instance == null){
			instance = new SyncThread();
		}
		instance.config = config;
		if(config.getRegisterServerUrls()!=null){
			String[] sers = config.getRegisterServerUrls().split(",");
			for(String server:sers){
				if(!config.getHostUrl().equals(server)){
					RegisterClient client = null;
					try{
						client = new RegisterClient(config.getClientTimeOut(),config.getClientConnectTimeOut(),
				    			config.getClientSleepTime(),config.getClientIdleStateTime());
						instance.servers.put(server,client);
						client.connect(server);
					} catch (ClientException e) {
						LogManager.warn(SyncThread.class,"连接注册服务器失败，创建注册服务器连接失败 Server=" + server);
					} catch (Exception e) {
						LogManager.warn(SyncThread.class,"连接注册服务器失败，创建注册服务器连接失败 Server=" + server);
					}
				}
			}
		}
		instance.thread = new Thread(instance);
		instance.thread.start();
	}

	/**
	 * 是否停止
	 */
	private boolean stop = false;
	

	/**
	 * 公共延迟方法
	 */
    private static void timeDelay(int time) {
		try {
			long t = time - System.currentTimeMillis() % time;
			if (t > 0) {
				Thread.sleep(t);
			}
		} catch (InterruptedException e) {
		}
	}
    
	/**
	 * 守护线程
	 */
	public void run() {
		stop = false;
		while(!stop){
			List<ServerInfo> serverLists = new ArrayList<ServerInfo>();
			synchronized(clusterServerInfos){
				serverLists.addAll(clusterServerInfos);
				clusterServerInfos.clear();
			}
			if(!serverLists.isEmpty()){
				Iterator<Entry<String,RegisterClient>> its = servers.entrySet().iterator();
				while(its.hasNext()){
					Entry<String,RegisterClient> entry = its.next();
					if(!entry.getValue().isActive()){
						try{
							RegisterClient client = entry.getValue();
							client.connect(entry.getKey());
							instance.servers.put(entry.getKey(),client);
						} catch (Throwable e) {
							LogManager.warn(SyncThread.class,"发送微服务信息到注册服务器失败 Server=" + entry.getKey());
						}
					}
					try{
						if(entry.getValue().isActive()){
							entry.getValue().syncServices(serverLists);
						}
					} catch (Throwable e) {
						LogManager.warn(this.getClass(),"同步微服务信息到注册服务器失败 Server=" + entry.getKey());
					}
				}
			}

			List<HostInfo> hostLists = new ArrayList<HostInfo>();
			synchronized(hostInfos){
				hostLists.addAll(hostInfos);
				hostInfos.clear();
			}
			if(!hostLists.isEmpty()){
				Iterator<Entry<String,RegisterClient>> its = servers.entrySet().iterator();
				while(its.hasNext()){
					Entry<String,RegisterClient> entry = its.next();
					if(!entry.getValue().isActive()){
						try{
							RegisterClient client = entry.getValue();
							client.connect(entry.getKey());
							instance.servers.put(entry.getKey(),client);
						} catch (Throwable e) {
							LogManager.warn(SyncThread.class,"发送服务器信息到注册服务器失败 Server=" + entry.getKey());
						}
					}
					try{
						if(entry.getValue().isActive()){
							entry.getValue().syncHosts(hostLists);
						}
					} catch (Throwable e) {
						LogManager.warn(this.getClass(),"同步服务器信息到注册服务器失败 Server=" + entry.getKey());
					}
				}
			}

			ServiceRoot.getServiceRoot().refresh(config.getActiveTime());
			if(config.getSyncThreadSleepTime()>0){
				timeDelay(config.getSyncThreadSleepTime());
			}
		}
	}
	
	/**
	 * 停止守护线程
	 */
	public static void stop() {
		if(instance!=null && instance.thread!=null){
			instance.stop = true;
			while(instance.thread.isAlive()){
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
				}
			}
		}

	}



}
